$include("js/prototype.js");
$include("js/constants.js");
$include("js/dwr/engine.js");
$include("js/dwr/util.js");
$include("js/dwr/interface/Validate.js");

function ValidateForm(name)
{
	this.name=name;  //要进行验证的Form的Name
	this.form=null;   //要进行验证的Form
	this.xml=null;  //存放验证规则的XML

	this.called=false;  //是否已经在初始化之前进行了检查
	this.succeed=false;  //是否已经完成了整个验证
	this.buffer=0;  //因为是异步的，这里要记录下来还有几个在进行的验证
	
	this.errors={};  //存放错误信息，里面是字段和错误信息的对应。
	this.fieldNames={}; //根据表单中国际化信息初始化的字段名
	var owner=this;  //保存指向自己的指针
	this.result=null;  //验证后调用的方法
	
	this.depot=new Array();  //当进行Remote调用时，把当前的节点存放在Depot里
		
	this.i18nMessages={  //系统信息集合
		cn:{
			badForm:"不是一个有效的Form！",
			configFileError:"验证文件格式错误！",
			findError:"验证过程中出现错误！",
			error1:"${field}不能为空！",
			error2:"${field}的值不符合要求！"
		},
		en:{
			badForm:" is not a active Form!",
			configFileError:"Check xml 's format is error!",
			findError:"Find a error at checking.",
			error1:"${field} can't is empty!",
			error2:"${field} isn't a real value!"
		}		
	};	
	
	//取回XML文件后进行初始化
	//注意：因为在构造方法中用到了这个方法，所以它一定要放在构造方法之前！
	this.init=function fun(request)
	{
		this.xml=request.responseXML;
		
		//如果已经调用过，对检查方法进行调用，用于解决在初始化完成前进行检查的问题
		if(this.called)
			this.check();
	}	
	
	//构造方法
	{
		this.form=document.forms[name];  //页面表单
		if(this.form==null) $error(this.i18n("badForm"));
		else
		{
			//取出表单里的国际化信息
			if(this.form[_constants["validateI18n"]]!=null)
			{
				var i18nStr=this.form[_constants["validateI18n"]].value;
				var i18nArray=i18nStr.split(",");  //将以","连接的字符串转换为字符串数组
				if(i18nArray.length>0)
				{
					for(var i=0;i<i18nArray.length;i++)
					{
						var temp=i18nArray[i].split("=");  //将以"="连接的字符串转换为字符串数组
						if(temp.length>0)
						{
							if(temp.length>1) this.fieldNames[temp[0]]=temp[1];  //表单中已定义的属性名
							else this.fieldNames[temp[0]]="";
						}
					}
				}
			}
		
			//从Form中取得验证规则XML文件的路径
			var validateXML=this.form[_constants["validateConfig"]].value;

			if(validateXML!=null)
			{
				var ajax=new Ajax.Request(validateXML,
					{
					method:'get',
					onComplete:function fun(request)
						{
							owner.init(request);
						}
					});
			}
		}
	}
	
	/*
	用于取出国际化信息，上下文中要有_lang常量
	*/
	this.i18n=function fun(name)
	{
		if(_lang==null || this.i18nMessages[_lang]==null) _lang="cn";
		if(this.i18nMessages[_lang]!=null)
		{
			return this.i18nMessages[_lang][name];
		}
		else return null;
	}
	
	/*
	对表单进行检查,结束时调用showErrors方法.
	返回值:true表示正确执行了验证,
		false表示验证的过程中有错误
	*/
	this.check=function fun()
	{
		if(this.xml!=null)
		{
			this.errors={};  //清空错误的信息
			
			try
			{
				this.checkForm();  //执行验证
			}
			catch (e)
			{
				alert(this.i18n("findError"));
				return false;
			}

			this.completeCheck();
		}
		else
		{
			this.called=true;  //如果没有完成初始化，把状态设定为已调用
		}
		
		return true;
	}
	/*
	表单验证
	*/
	this.checkForm=function fun()
	{
		var forms=this.xml.getElementsByTagName("form");  //xml文件中的form节点
		if(forms.length==0)  //未找到form节点时
		{	
			//check.xml格式验证
			alert(this.i18n("configFileError"));
			return false;
		}
		
		//验证一级field节点的数据
		var fields=forms[0].childNodes;  //form中的子节点
		for(var i=0;i<fields.length;i++)
		{
			if(fields[i].tagName=="field")  //子节点名为field时，执行验证
			{ 
				this.checkField(fields[i]);
			}
		}
		
		this.succeed=true;  //表单验证完成
	}
	
	//读取一级节点field
	this.checkField=function fun(field) 
	{	
		var fieldName=field.getAttribute("name");  //属性名称
		var rules=field.childNodes;  //要求的规则
		
		//验证每个规则
		for(var j=0;j<rules.length;j++)
		{
			if(rules[j].tagName=="rule")
			{
				var rule=rules[j];  //规则节点
				this.checkRule(fieldName,rule);  //检验属性是否符合验证规则
			}
		}
	}			
	//检验属性是否符合验证规则
	this.checkRule=function fun(fieldName,rule)
	{
		var ruleName=rule.getAttribute("name");  //规则名称
		var fieldValue=this.form[fieldName].value;  //表单属性值

		var parameters={};  //规则参数
		{
			var attributes=rule.attributes;
			if(attributes!=null)
			{
				for(var n=0;n<attributes.length;n++)
				{
					var attribute=attributes[n];
					parameters[attribute.name]=attribute.value;
				}
			}		
		}
		
		if(this.rules[ruleName]!=null)  //内部支持的验证规则中存在指定的规则时
		{
			var result=this.rules[ruleName](fieldValue,parameters);  //执行指定的规则验证
			this.checkRuleResult(result,rule);  //规则验证结果处理
		}
		else  //内部支持的验证规则中不存在指定的规则时，调用外部规则
		{
			this.checkRemoteRule(ruleName,fieldValue,parameters,rule);
		}
	}
	
	this.checkRemoteRule=function fun(ruleName,fieldValue,parameters,rule)
	{
		var len=this.depot.length;
		this.depot[len]=rule;  //存储当前要验证的规则节点
		Validate.check(ruleName,fieldValue,parameters,len,this.checkRemoteRuleResult);
		this.buffer++;  //验证数+1
	}
	
	this.checkRemoteRuleResult=function fun(result)
	{
		if(result!=null)
		{
			var temp=result.split("\n");  //验证规则节点在depot中的位置\n验证结果
			if(temp.length>0)
			{
				var rule=owner.depot[parseInt(temp[0])];  //取回验证规则节点
				if(temp.length>1)  owner.checkRuleResult(temp[1],rule);  //规则验证结果处理
				else owner.checkRuleResult(null,rule);  
			}
		}

		owner.buffer--;  //验证数-1
		owner.completeCheck();
	}
	//执行验证后的结果处理要求
	this.checkRuleResult=function fun(result,rule)
	{
		var fieldName=rule.parentNode.getAttribute("name");  //属性名
		var ruleError=rule.getAttribute("error");  //验证结果处理要求
		
		//记录错误
		if(result!=null && ruleError!="false")
		{
			owner.addError(fieldName,result);
		}
		else
		{
			//进行依赖验证
			var dependents=rule.childNodes;
			for(var k=0;k<dependents.length;k++)
			{
				if(dependents[k].tagName=="dependent")
				{
					var fields=dependents[k].childNodes;
					for(var z=0;z<fields.length;z++)
					{
						if(fields[z].tagName=="field")
						{
							this.checkField(fields[z]);
						}
					}
				}
			}			
		}
	}
	
	/*
	添加错误信息
		name:错误的字段名称
		error:错误的内容
	*/
	this.addError=function fun(name,error)
	{
		if(error!=null)
		{
			var fieldName=name;
			if(this.fieldNames[name]!=null)
				fieldName=this.fieldNames[name];
			error=error.replace("${field}",fieldName);
		
			if(this.errors[name]!=null)
				this.errors[name]+="\n"+error;
			else
				this.errors[name]=error;
		}
	}
	
	/*
	用于在检查完毕后进行相关的处理
	*/
	this.completeCheck=function fun()
	{
		if(this.succeed && this.buffer<1)  //验证全部执行完毕
		{
			if(this.result!=null)  //存在验证后的处理方法时
			{
				var result=true;  //验证不存在错误
				for(var key in this.errors)  //errors有数据时，验证存在错误
				{
					result=false;  
					break;
				}
				this.result(result);  //执行验证后的处理方法
			}
			else  //不存在验证后的处理方法时
			{
				this.showErrors();
			}
		}
	}
	
	//显示出错误的信息，为默认的错误处理方法
	this.showErrors=function fun()
	{
		var msg="";
		for(var key in this.errors)
		{
			msg+=this.errors[key];
			msg+="\n";
		}
		alert(msg);	
	}
	
	/**
	内部支持的验证规则在这里定义
	所有的方法都有两个参数
		value:字段的值
		parameters:参数所Map
	*/

	this.rules={
		required:function fun(value,parameters)  //必填验证
		{
			if(value==null || value=="")
				return owner.i18n("error1");
			return null;
		},
		equals:function fun(value,parameters)  //等值验证（至少等于其中一值）
		{
			for(key in parameters)
			{
				if(key!=null && key.length>4)
				{
					if("value"==key.substr(0,5))
					{
						if(value==parameters[key]) return null;
					}
				}
			}
			return owner.i18n("error2");
		}
	};	

}


